package space.cloaking.ext.tomcat;

import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.loader.WebappLoader;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

public class ConfigurableWebappLoader extends WebappLoader {

    private static final Log LOG = LogFactory.getLog(ConfigurableWebappLoader.class);

    private URLClassLoader mConfigClassLoader;

    public ConfigurableWebappLoader() {
        this(null);
    }

    public ConfigurableWebappLoader(ClassLoader parent) {
        super(parent);
        setLoaderClass(null);
    }

    @Override
    public void setLoaderClass(String loaderClass) {
        // Force set to ConfigurableWebappClassLoader
        super.setLoaderClass(ConfigurableWebappClassLoader.class.getName());
    }

    @Override
    protected void startInternal() throws LifecycleException {
        super.startInternal();

        Context context = getContext();
        if(null == context) {
            return;
        }

        String docBase = context.getDocBase();
        if(null == docBase || docBase.isEmpty()) {
            return;
        }
        File docFile = new File(docBase);
        String parentPath = docFile.getParent();
        if(null == parentPath) {
            return;
        }
        String configPath = parentPath + File.separator + "config";
        LOG.info("Using config path: " + configPath);

        URL url;
        try {
            url = new File(configPath).toURI().toURL();
        } catch(MalformedURLException e) {
            e.printStackTrace();
            return;
        }

        mConfigClassLoader = new URLClassLoader(new URL[] { url });
        ((ConfigurableWebappClassLoader) getClassLoader()).setConfigDelegate(mConfigClassLoader);

         URL dubboUrl = mConfigClassLoader.getResource("dubbo.properties");
         LOG.info("Dubbo url : " + dubboUrl);
    }

    @Override
    protected void stopInternal() throws LifecycleException {
        super.stopInternal();
        if(null != mConfigClassLoader) {
            try {
                mConfigClassLoader.close();
            } catch(IOException e) { LOG.warn("Close ConfigClassLoader failed.", e); }
        }
    }

    private static String resolveEnvParameter(String text) {
        StringBuilder resolved = new StringBuilder();

        while(true) {
            int startIndex = text.indexOf("${");
            if(startIndex < 0) {
                break;
            }

            resolved.append(text.substring(0, startIndex));
            text = text.substring(startIndex);

            int endIndex = text.indexOf("}");
            String name = text.substring(2  /* length of "${" */, endIndex);
            if(!name.isEmpty()) {
                resolved.append(System.getenv(name));
            }
            text = text.substring(3  /* length of "${}" */ + name.length());
        }

        resolved.append(text);

        return resolved.toString();
    }
}
